package cn.lm.activit.module;

import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.Task;
import org.activiti.engine.ActivitiEngineAgenda;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricActivityInstanceQuery;
import org.activiti.engine.impl.HistoricActivityInstanceQueryImpl;
import org.activiti.engine.impl.Page;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.interceptor.CommandContextFactory;
import org.activiti.engine.impl.persistence.entity.*;
import org.activiti.engine.impl.util.ProcessDefinitionUtil;
import org.apache.commons.lang3.StringUtils;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author lm_jcf
 * @date 2018/7/19 20:34
 */
public class TurnProcHandle implements Command<Void> {

    private String currentTaskId;

    private String targetTaskId;

    private String assignee;

    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();


    public TurnProcHandle(String currentTaskId,String targetTaskId) {
        this.currentTaskId = currentTaskId;
        this.targetTaskId = targetTaskId;
    }

    public Void execute(CommandContext commandContext) {
        ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();

        // 任务对象管理器
        TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
        HistoricTaskInstanceEntityManager hiTaskEntityManager = commandContext.getHistoricTaskInstanceEntityManager();
        HistoricActivityInstanceEntityManager hiActivityInstanceEntityManager = commandContext.getHistoricActivityInstanceEntityManager();
        // 当前任务的任务对象
        TaskEntity currentTaskEntity = taskEntityManager.findById(currentTaskId);
        HistoricTaskInstanceEntity targetHistoricTask = hiTaskEntityManager.findById(targetTaskId);

        // 获取当前任务节点的执行对象
        ExecutionEntity executionEntity = executionEntityManager.findById(currentTaskEntity.getExecutionId());

        // 获取流程定义模型对象
        Process process = ProcessDefinitionUtil.getProcess(executionEntity.getProcessDefinitionId());

        // 生成连线到指定节点：根据节点ID
        FlowElement targetFlowElement = process.getFlowElement(targetHistoricTask.getTaskDefinitionKey());
        // 改变办理人变量为目标节点的办理人
        executionEntity.setVariable("assigneeId",targetHistoricTask.getAssignee());
        // 更改当前任务执行对象的连线
        executionEntity.setCurrentFlowElement(targetFlowElement);

        ActivitiEngineAgenda agenda = commandContext.getAgenda();
        agenda.planContinueProcessInCompensation(executionEntity);

        cleanHistoricRecord(commandContext);

        return null;
    }

    public void cleanHistoricRecord(CommandContext commandContext) {
        TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
        HistoricTaskInstanceEntityManager hiTaskEntityManager = commandContext.getHistoricTaskInstanceEntityManager();
        HistoricActivityInstanceEntityManager hiActivityInstanceEntityManager = commandContext.getHistoricActivityInstanceEntityManager();

        // 当前任务的任务对象
        TaskEntity currentTaskEntity = taskEntityManager.findById(currentTaskId);
        HistoricTaskInstanceEntity currentHistoricTask = hiTaskEntityManager.findById(currentTaskId);
        HistoricTaskInstanceEntity targetHistoricTask = hiTaskEntityManager.findById(targetTaskId);

        // 删除当前任务所有相关信息：历史、下属子任务、变量
        taskEntityManager.delete(currentTaskEntity);
        hiTaskEntityManager.delete(currentHistoricTask);
        // 删除目标任务历史
        hiTaskEntityManager.delete(targetHistoricTask);


        // 手动查询对应节点实例 并删除
        String customQueryT_ActInstSql = "select * from act_hi_actinst where TASK_ID_ in (#{targetTaskId},#{currentTaskId})";
        List<HistoricActivityInstance> activityInstancesList = processEngine.getHistoryService()
                .createNativeHistoricActivityInstanceQuery()
                .sql(customQueryT_ActInstSql)
                .parameter("targetTaskId", targetTaskId)
                .parameter("currentTaskId", currentTaskId)
                .list();
        if (activityInstancesList != null && activityInstancesList.size() > 0) {
            Set<String> activityIdSet = new HashSet<String>();
            for (HistoricActivityInstance historicActivityInstance : activityInstancesList) {
                activityIdSet.add(historicActivityInstance.getId());
            }

            if (activityIdSet.size() > 0) {
                String deleteSql = "delete from act_hi_actinst where ID_ in (%s)";
                deleteSql = String.format(deleteSql,StringUtils.join(activityIdSet,","));
                processEngine.getHistoryService()
                        .createNativeHistoricActivityInstanceQuery()
                        .sql(deleteSql)
                        .singleResult();

            }
        }
    }
}
